#!/usr/bin/python3
import struct
import sys
import math
from myerror import *

class GetData:
    def __init__(self,hisd) -> None:
        self.hisd=hisd
    def getdata_by_pixlin(self,hpix:float,hlin:float) -> int:
        R_C=struct.unpack("f",self.hisd.navicorr_info["RoCenterColumn"])[0]
        R_L=struct.unpack("f",self.hisd.navicorr_info["RoCenterLine"])[0]
        R_A=struct.unpack("d",self.hisd.navicorr_info["RoCorrection"])[0]/1000.0/1000.0
        totalHeaderLen=int.from_bytes(self.hisd.basic_info["totalHeaderLen"],sys.byteorder)
        nLin=struct.unpack("H",self.hisd.data_info["nLin"])[0]
        nPix=struct.unpack("H",self.hisd.data_info["nPix"])[0]
        strLinNo=struct.unpack("H",self.hisd.segm_info["strLineNo"])[0]
        dataLen=int.from_bytes(self.hisd.basic_info["dataLen"],sys.byteorder)
        byteorder_in_file=int.from_bytes(self.hisd.basic_info["byteOrder"],sys.byteorder)

        #init
        self.sout=struct.unpack("H",self.hisd.calib_info["outCount"])
        # shift correction table
        if self.hisd.correcttable["flag"]==0:
            self.__comp_table()
        if self.hisd.correcttable["flag"]==1:
            # shift amount for column and line direction
            i=int(hlin+0.5)-self.hisd.correcttable["startLineNo"]
            if i<0:
                i=0
            elif self.hisd.correcttable["lineNum"]-1<i:
                i=self.hisd.correcttable["lineNum"]-1<i
            pshift=self.hisd.correcttable["cmpCoff"][i]
            lshift=self.hisd.correcttable["cmpLoff"][i]
            # shift correction
            hpix=hpix-pshift
            hlin=hlin-lshift
        # rotational correction
        hlin2=(hlin-R_L)*math.cos(R_A)-(hpix-R_C)*math.sin(R_A)+R_L
        hpix2=(hpix-R_C)*math.cos(R_A)+(hlin-R_L)*math.sin(R_A)+R_C
        hlin=hlin2
        hpix=hpix2
        # Nearest Neighbor
        ll=int(hlin+0.5)-strLinNo
        pp=int(hpix+0.5)-1
        
        # check ll and pp
        if ll<0 or nLin<ll:
            return ERROR_DATA
        if pp<0 or nPix<pp:
            return ERROR_DATA
        #read date
        short_struct=struct.Struct("H")
        seek_pt=totalHeaderLen+(ll*nPix+pp)*short_struct.size
        if seek_pt>totalHeaderLen+dataLen:
            return ERROR_DATA
        self.hisd.fp.seek(seek_pt,0)
        self.sout=self.hisd.fp.read(short_struct.size)
        if self.__byteorder()!=byteorder_in_file:
            self.sout=bytes(reversed(self.sout))
        sout2=struct.unpack("H",self.sout)[0]
        self.sout=sout2
        #print(self.sout)
        return NORMAL_END


    

    def __comp_table(self):
        correctNum=int.from_bytes(self.hisd.navicorr_info["correctNum"],sys.byteorder)
        lineNo=[]
        for n in self.hisd.navicorr_info["lineNo"]:
            lineNo.append(int.from_bytes(n,sys.byteorder))
        columnShift=[]
        lineShift=[]
        for ii in range(int.from_bytes(self.hisd.navicorr_info["correctNum"],sys.byteorder)):
            columnShift.append(int.from_bytes(self.hisd.navicorr_info["columnShift"][ii],sys.byteorder))
            lineShift.append(int.from_bytes(self.hisd.navicorr_info["lineShift"][ii],sys.byteorder))
        # make table
        if correctNum<2:
            return ERROR_DATA
        else:
            self.hisd.correcttable["startLineNo"]=lineNo[0]
            self.hisd.correcttable["lineNum"]=lineNo[correctNum-1]-lineNo[0]+1
            if self.hisd.correcttable["lineNum"]<2:
                return ERROR_DATA
            # init
            self.hisd.correcttable["cmpCoff"]=[]
            self.hisd.correcttable["cmpLoff"]=[]
            for i in range(self.hisd.correcttable["lineNum"]):
                self.hisd.correcttable["cmpCoff"].append(0.0)
                self.hisd.correcttable["cmpLoff"].append(0.0)
            # navigation correction table
            for i in range(correctNum-1):
                lineNo1=lineNo[i]
                lineNo2=lineNo[i+1]
                coff1=columnShift[i]
                coff2=columnShift[i+1]
                loff1=lineShift[i]
                loff2=lineShift[i+1]
                
                ilineNo=lineNo1
                while ilineNo<=lineNo2:
                    j=ilineNo-self.hisd.correcttable["startLineNo"]
                    if 0<=j and j<=self.hisd.correcttable["lineNum"]:
                        self.hisd.correcttable["cmpCoff"][j]=coff1+(coff2-coff1)/float(lineNo2-lineNo1)*float(ilineNo-lineNo1)
                        self.hisd.correcttable["cmpLoff"][j]=loff1+(loff2-loff1)/float(lineNo2-lineNo1)*float(ilineNo-lineNo1)
                    ilineNo=ilineNo+1
        self.hisd.correcttable["flag"]=1
        return NORMAL_END


    def __byteorder(self):
        if sys.byteorder=="little":
            return 0
        elif sys.byteorder=="big":
            return 1
        else:
            return -1